﻿#include "function_circle_match.h"
#include "para.h"

extern MyPARA my_para;
// Procedures 
void circleMatch(HObject ho_image, HObject *ho_region_show, HTuple hv_row1, HTuple hv_column1,
	HTuple hv_row2, HTuple hv_column2, HTuple hv_threshold_low, HTuple hv_threshold_high,
	HTuple *hv_radius, HTuple *hv_ret)
{

	// Local iconic variables
	HObject  ho_Rectangle, ho_ImageReduced, ho_Regions;
	HObject  ho_RegionFillUp, ho_ConnectedRegions, ho_ConnectedRegionsSelect;
	HObject  ho_Contours;

	// Local control variables
	HTuple  hv_row, hv_column, hv_StartPhi, hv_EndPhi;
	HTuple  hv_PointOrder;

	GenRectangle1(&ho_Rectangle, hv_row1, hv_column1, hv_row2, hv_column2);
	ReduceDomain(ho_image, ho_Rectangle, &ho_ImageReduced);


	Threshold(ho_ImageReduced, &ho_Regions, hv_threshold_low, hv_threshold_high);
	FillUp(ho_Regions, &ho_RegionFillUp);
	Connection(ho_RegionFillUp, &ho_ConnectedRegions);

	SelectShapeStd(ho_ConnectedRegions, &ho_ConnectedRegionsSelect, "max_area", 70);
	SelectShapeStd(ho_ConnectedRegions, &(*ho_region_show), "max_area", 70);

	GenContourRegionXld((*ho_region_show), &ho_Contours, "border");

	FitCircleContourXld(ho_Contours, "algebraic", -1, 0, 0, 3, 2, &hv_row, &hv_column,
		&(*hv_radius), &hv_StartPhi, &hv_EndPhi, &hv_PointOrder);
	(*hv_ret) = 1;
	return;
}



FunctionCircleMatch::FunctionCircleMatch(QDialog* parent, QSettings* qsettings , QString section) : QDialog(parent)
{

    m_qsettings = qsettings;
    m_section   = section;
    //m_model_image_path = QCoreApplication::applicationDirPath() + "/" + m_model_image_path;

    this->setWindowTitle(("circle "));
    QRect desktop_rect = QApplication::desktop()->geometry();
    double ratio_x = desktop_rect.width()/1920.0;
    double ratio_y = desktop_rect.height()/1080.0;

    move(0,0);
    setFixedSize(1920*ratio_x,1010*ratio_y);

    m_view = new MyQGraphicsView(this);
    m_view->setGeometry(660 * ratio_x, 0, 1000 * 1.25 * ratio_x, 800 * 1.25 * ratio_y);



    m_view->m_graphics_shape_rect = new GraphicsShapeRect(100,100,100,100,Qt::blue);
    m_view->m_scene->addItem(m_view->m_graphics_shape_rect);
    QRectF qrectf = m_view->m_graphics_shape_rect->boundingRect();
    row1 = (int)qrectf.y();
    column1 = (int)qrectf.x();
    row2 = (int)(qrectf.y() + qrectf.height());
    column2 = (int)(qrectf.x() + qrectf.width());


    
    connect(m_view->m_graphics_shape_rect, &GraphicsShapeRect::sendMessage, m_view->m_pixmapItem, &MyQGraphicsPixmapItem::receiveMessage);

    QSize control_size(220*ratio_x,40*ratio_y);

    QWidget* p = new QWidget(this);
    p->move(0*ratio_x,0*ratio_y);
    p->setFixedSize(600*ratio_x,800*ratio_y);

    QGridLayout *qgridLayout = new QGridLayout();
    p->setLayout(qgridLayout);

    int index = 0;

    QSize ButtonSize(220 * ratio_x, 40 * ratio_y);


    m_qlabel_threshold_low = new QLabel();
    m_qlabel_threshold_low->setText("GrayLow");
    m_qlabel_threshold_low->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_threshold_low,index,0);
    index++;

    m_qspinbox_threshold_low = new QSpinBox();
    m_qspinbox_threshold_low->setFixedSize(control_size);
    m_qspinbox_threshold_low->setMinimum(0);
    m_qspinbox_threshold_low->setMaximum(255);
	m_qspinbox_threshold_low->setReadOnly(true);
    qgridLayout->addWidget(m_qspinbox_threshold_low,index,0);
    
    m_qslider_threshold_low = new QSlider(Qt::Horizontal);
    m_qslider_threshold_low->setTickPosition(QSlider::NoTicks);
    m_qslider_threshold_low->setSingleStep(1);
    m_qslider_threshold_low->setMinimum(0);
    m_qslider_threshold_low->setMaximum(255);
    
    qgridLayout->addWidget(m_qslider_threshold_low,index,1);
    index++;

    m_qlabel_threshold_high = new QLabel();
    m_qlabel_threshold_high->setText("GrayHigh");
    m_qlabel_threshold_high->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_threshold_high,index,0);
    index++;

    m_qspinbox_threshold_high = new QSpinBox();
    m_qspinbox_threshold_high->setFixedSize(control_size);
    m_qspinbox_threshold_high->setMinimum(1);
    m_qspinbox_threshold_high->setMaximum(255);
	m_qspinbox_threshold_high->setReadOnly(true);
    qgridLayout->addWidget(m_qspinbox_threshold_high,index,0);
    
    m_qslider_threshold_high = new QSlider(Qt::Horizontal);
    m_qslider_threshold_high->setTickPosition(QSlider::NoTicks);
    m_qslider_threshold_high->setSingleStep(1);
    m_qslider_threshold_high->setMinimum(1);
    m_qslider_threshold_high->setMaximum(255);
	qgridLayout->addWidget(m_qslider_threshold_high, index, 1);
	index++;

	m_qlabel_radius_low = new QLabel();
    m_qlabel_radius_low->setText("RadiusMin");
	m_qlabel_radius_low->setFixedSize(control_size);
	qgridLayout->addWidget(m_qlabel_radius_low, index, 0);

	m_qspinbox_radius_low = new QSpinBox();
	m_qspinbox_radius_low->setFixedSize(control_size);
	m_qspinbox_radius_low->setMinimum(0);
	m_qspinbox_radius_low->setMaximum(2000);
	qgridLayout->addWidget(m_qspinbox_radius_low, index, 1);
	index++;

	m_qlabel_radius_high = new QLabel();
    m_qlabel_radius_high->setText("RadiusMax");
	m_qlabel_radius_high->setFixedSize(control_size);
	qgridLayout->addWidget(m_qlabel_radius_high, index, 0);


	m_qspinbox_radius_high = new QSpinBox();
	m_qspinbox_radius_high->setFixedSize(control_size);
	m_qspinbox_radius_high->setMinimum(0);
	m_qspinbox_radius_high->setMaximum(2000);
	qgridLayout->addWidget(m_qspinbox_radius_high, index, 1);
	index++;


    m_pushbutton_save_parameter = new QPushButton(this);
    m_pushbutton_save_parameter->setFixedSize(control_size);
    m_pushbutton_save_parameter->setText("Save");
    connect(m_pushbutton_save_parameter, &QPushButton::clicked, this, &FunctionCircleMatch::saveParameter);
    qgridLayout->addWidget(m_pushbutton_save_parameter, index,0);
	index++;



	

    m_pushbutton_show_orign_image = new QPushButton(this);
    m_pushbutton_show_orign_image->setFixedSize(control_size);
    m_pushbutton_show_orign_image->setText("ShowOrign");
    connect(m_pushbutton_show_orign_image, &QPushButton::clicked, this,[=]() {
        QImage q_image = matToQImage(m_image);
        m_view->setImage(q_image,"");
        return true;
    });
    qgridLayout->addWidget(m_pushbutton_show_orign_image, index,0);

    m_pushbutton_detection = new QPushButton(this);
    m_pushbutton_detection->setFixedSize(control_size);
    m_pushbutton_detection->setText("Detection");
    connect(m_pushbutton_detection, &QPushButton::clicked, this, &FunctionCircleMatch::detectionImage);
    qgridLayout->addWidget(m_pushbutton_detection, index,1);
    
    index++;
    m_pushbutton_return = new QPushButton(this);
    m_pushbutton_return->setFixedSize(control_size);
    m_pushbutton_return->setText("Exit");
    qgridLayout->addWidget(m_pushbutton_return, index, 0);
    connect(m_pushbutton_return, &QPushButton::clicked, this, [=]() {
        this->hide();
        });

    


    loadParameter(m_path_para,m_section);

	m_qslider_threshold_low->setValue(m_qspinbox_threshold_low->value());
	connect(m_qslider_threshold_low, &QSlider::valueChanged, this, [=](int value) {
		
		if (m_qspinbox_threshold_high->value() <= m_qspinbox_threshold_low->value())
		{
			m_qspinbox_threshold_low->setValue(m_qspinbox_threshold_high->value() - 1);
			m_qslider_threshold_low->setValue(m_qspinbox_threshold_high->value() - 1);

		}
		else
		{
			m_qspinbox_threshold_low->setValue(value);
		}
//        testImage();

	});
	m_qslider_threshold_high->setValue(m_qspinbox_threshold_high->value());
	connect(m_qslider_threshold_high, &QSlider::valueChanged, this, [=](int value) {
		//m_qspinbox_threshold_high->setValue(value);
		if (m_qspinbox_threshold_high->value() <= m_qspinbox_threshold_low->value())
		{
			m_qspinbox_threshold_high->setValue(m_qspinbox_threshold_low->value() + 1);
			m_qslider_threshold_high->setValue(m_qspinbox_threshold_low->value() + 1);
			return;
		}
		else
		{
			m_qspinbox_threshold_high->setValue(value);
		}

//        testImage();


	});

	m_image = imread("model.png", IMREAD_UNCHANGED);
	

}

FunctionCircleMatch::~FunctionCircleMatch()
{
    ;
}



bool FunctionCircleMatch::detection( HObject image_in,QString& message)
{
   /* if (m_image.empty())
    {
        message += "检测图像为空 ";
        return false;
    }*/

    try
    {
        HTuple hv_value, hv_ret;
        circleMatch(image_in, &region_out,row1, column1, row2, column2, m_qspinbox_threshold_low->value(),m_qspinbox_threshold_high->value(),&hv_value,&hv_ret);

        m_radius =  hv_value[0].D();

		
		if (m_radius < m_radius_low)
		{
			message = "ng circle radius:" + QString::number(m_radius);
			return false;
		}
		if (m_radius > m_radius_high)
		{
			message = "ng circle radius:" + QString::number(m_radius);
			return false;
		}

		return true;
    }
   
	catch (HException &HDevExpDefaultException)
	{
		message = HDevExpDefaultException.ErrorMessage();
		return false;
	}
    return true;
}

void FunctionCircleMatch::detectionImage()
{
    if(m_image.empty())
    {
        //QMessageBox::information(nullptr,"","没有图像");
        return;
    }

    QString message;
	HObject image = matToHImage(m_image);
	bool state = detection(image, message);
	if (!state)
	{
		//message += "ng circle" + QString::number(m_radius);
	}
	else
	{
		message += "ok circle" + QString::number(m_radius); 
	}
    //detection(m_image.clone(),message);

    Mat image_show = m_image.clone();
    draw(image_show, image_show);

    QImage q_image = matToQImage(image_show);
    m_view->setImage(q_image, message);
  
}

void FunctionCircleMatch::draw( Mat image_in,Mat& image_out)
{
    if(image_in.empty())
        return;
    if (image_in.channels() == 1)
    {
        cvtColor(image_in, image_out, COLOR_GRAY2BGR);
    }
    image_out = drawRegion(image_out, region_out,Scalar(0, 255, 0));
    GenEmptyRegion(&region_out);
    //rectangle(image_out, Rect(column1,row1,column2-column1,row2-row1), Scalar(0, 255, 0), 1);

}

void FunctionCircleMatch::loadParameter(QString path_in,QString section)
{
    m_path_para = path_in;
    m_section   = section;
    try
    {

        

 
        row1 = m_qsettings->value(section + "/" + "row1",100).toInt();
        column1 = m_qsettings->value(section + "/" + "column1",100).toInt();
        row2 = m_qsettings->value(section + "/" + "row2",200).toInt();
        column2 = m_qsettings->value(section + "/" + "column2",200).toInt();

        m_view->setRectPose(row1, column1, row2, column2);

		m_qspinbox_threshold_low->setValue(m_qsettings->value(section + "/" + "threshold_low").toInt());
		m_qspinbox_threshold_high->setValue(m_qsettings->value(section + "/" + "threshold_high").toInt());

		m_radius_low = m_qsettings->value(section + "/" + "m_radius_low").toInt();
		m_radius_high = m_qsettings->value(section + "/" + "m_radius_high").toInt();

		m_qspinbox_radius_low->setValue(m_radius_low);
		m_qspinbox_radius_high->setValue(m_radius_high);

    }
    catch(exception& error)
    {
        //QMessageBox::critical(nullptr,error.what() , m_section + "参数需要重新设置");
    }

    return ;
}

void FunctionCircleMatch::saveParameter()
{
    try
    {

        QRectF qrectf = m_view->m_graphics_shape_rect->boundingRect();
        row1 = m_view->m_graphics_shape_rect->pos().y() + (int)qrectf.y();
        column1 = m_view->m_graphics_shape_rect->pos().x() + (int)qrectf.x();
        row2 = m_view->m_graphics_shape_rect->pos().y() + (int)(qrectf.y() + qrectf.height());
        column2 = m_view->m_graphics_shape_rect->pos().x() + (int)(qrectf.x() + qrectf.width());

        

		m_radius_low   = m_qspinbox_radius_low->value();
		m_radius_high  = m_qspinbox_radius_high->value();

		

		if (my_para.m_login_privilege >= 2)
		{
			m_qsettings->setValue(m_section + "/" + "row1", row1);
			m_qsettings->setValue(m_section + "/" + "column1", column1);
			m_qsettings->setValue(m_section + "/" + "row2", row2);
			m_qsettings->setValue(m_section + "/" + "column2", column2);

			m_qsettings->setValue(m_section + "/" + "threshold_low", m_qspinbox_threshold_low->value());
			m_qsettings->setValue(m_section + "/" + "threshold_high", m_qspinbox_threshold_high->value());
			m_qsettings->setValue(m_section + "/" + "m_radius_low", m_radius_low);
			m_qsettings->setValue(m_section + "/" + "m_radius_high", m_radius_high);

		}

    }
    catch(exception& error)
    {
        //QMessageBox::critical(nullptr,error.what() , m_section + "para error");
    }
}

bool FunctionCircleMatch::showDialog()
{
    QImage q_image = matToQImage(m_image);
    m_view->setImage(q_image, "");
    return true;
}

